﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Web;
using TagCore;
using HtmlAgilityPack;

namespace GoogleQuery
{
    public class GoogleResponse : GoogleWeb, IMusicData
    {
        private string urlRoot;
        private string resultUrl;
        private string artist;
        private int width;
        private int height;
        byte[] image = null;

        public GoogleResponse(string urlRoot, HtmlNode node)
        {
            this.urlRoot = urlRoot;
            ParseSearchRequest(node);
        }

        private void ParseSearchRequest(HtmlNode node)
        {
            string srch = "href=";
            string res = node.OuterHtml.ToString();
            string refUrl;

            int start = res.IndexOf(srch);
            if (start != -1)
            {
                start += srch.Length + 1;
                int end = res.IndexOf('"', start);
                if (end != -1)
                {
                    refUrl = res.Substring(start, end - start);
                    SetValues(refUrl);
                }
            }
        }

        private void SetValues(string refUrl)
        {
            resultUrl = refUrl.Replace("&amp;", "&");
            string[] vals = resultUrl.Split('&');
            foreach (string val in vals)
            {
                if (val.StartsWith("w="))
                {
                    string[] s = val.Split('=');
                    if (s.Length > 1) { width = Convert.ToInt32(s[1]); }
                }
                else if (val.StartsWith("h="))
                {
                    string[] s = val.Split('=');
                    if (s.Length > 1) { height = Convert.ToInt32(s[1]); }
                }
                else if (val.StartsWith("imgrefurl="))
                {
                    string[] s = val.Split('=');
                    if (s.Length > 1) { artist = s[1]; }
                }
            }
        }

        private byte[] ReadImage()
        {
            string url = urlRoot + resultUrl;
            byte[] res = GetWebRequest(url);

            string imageUrl = GetImageUrl(res);
            try
            {
                res = GetWebRequest(imageUrl);
                return res;
            }
            catch
            {
                return null;
            }
        }

        private string GetImageUrl(byte[] result)
        {
            string srch = "image_url=";
            MemoryStream ms = new MemoryStream(result);
            doc.Load(ms);

            HtmlNodeCollection nodes = doc.DocumentNode.SelectNodes("//a[@class='sl']");
            if (nodes != null)
            {
                foreach (HtmlNode n in nodes)
                {
                    string html = n.OuterHtml;
                    int start = html.IndexOf(srch);
                    if (start != -1)
                    {
                        start += srch.Length;
                        int end = html.IndexOf('"', start);
                        if (end != -1)
                        {
                            string imageUrl = FixupImageUrl(html.Substring(start, end - start));
                            return imageUrl;
                        }
                    }
                }
            }
            return string.Empty;
        }

        private string FixupImageUrl(string url)
        {

            string final = HttpUtility.UrlDecode(url);
/*
            string final = url.Replace("%3F", "?");
            final = final.Replace("%3D", "=");
            final = final.Replace("%3B", ";");
            */
            return final;
        }

        #region Public
        public string Title
        {
            get
            {
                return "Google Search";
            }
            set
            {
            }
        }

        public string Album
        {
            get
            {
                return string.Format("{0} x {1}", width, height); 
            }
            set
            {
            }
        }

        public uint Year
        {
            get
            {
                return 1900;
            }
            set
            {
            }
        }

        public string[] Artists
        {
            get
            {
                return new string[] { artist };
            }
            set
            {
            }
        }

        public string[] AlbumArtists
        {
            get
            {
                return new string[0];
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        public string Genre
        {
            get
            {
                return string.Empty;
            }
            set
            {
            }
        }

        public string Comments
        {
            get
            {
                return string.Empty;
            }
            set
            {
            }
        }

        public uint Track
        {
            get
            {
                return 0;
            }
            set
            {
            }
        }

        public byte[] Image
        {
            get
            {
                if (image == null)
                    image = ReadImage();

                return image;
            }
            set
            {
                throw new NotImplementedException();
            }
        }
        #endregion
    }
}
